"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.
"""

"""
Case Type   : 资源池化
Case Name   : 资源池化场景下，无任何业务压力, 查询节点reform信息
Create At   : 2024-04-07
Owner       : zhongchengzhi
Description :
    1、手动关闭备节点2
    2、主节点连接数据库并查询节点reform信息
    3、手动启动备节点2
    4、主节点连接数据库并查询节点reform信息
    5、集群failover并查询节点reform信息
    6、手动关闭集群
    7、手动开启集群
    8、手动进行switchover
    9、在新的主节点连接数据库并查询节点reform信息
   10、恢复集群原始状态
Expect      :
    1、关闭节点2 OK
    2、集群发生normal reform，节点1稳定，节点2退出集群
    3、启动节点2 OK
    4、集群发生normal reform，节点1稳定，节点2加入集群
    5、集群发生failover成功
    6、关闭集群 OK
    7、开启集群 OK
    8、switchover正常
    9、集群发生switchover，节点1和节点2均稳定
    10、恢复集群原始状态成功,集群状态正常
History     :
    1、2024-04-07 创建
    2、2025-07-12 改造用例为1p1s环境可执行
"""
import os
import unittest
import time
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import macro

Primary_SH = CommonSH('PrimaryDbUser')


@unittest.skipIf(1 == Primary_SH.get_node_num(), '单机环境不执行')
class SharedStorage(unittest.TestCase):

    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.constant = Constant()
        self.s1_comsh = CommonSH('Standby1DbUser')

    def test_shared_storage(self):
        text = '-----step1:手动关闭备节点2; expect:关闭节点2 OK-----'
        self.log.info(text)
        status = Primary_SH.exec_cm_ctl(mode='stop', param='-n 2')
        self.log.info(status)
        self.assertIn('cm_ctl: stop node successfully.', status, '执行失败' + text)

        text = '-----step2:主节点连接数据库并查询节点reform信息; expect:集群发生normal reform，节点1稳定，节点2退出集群-----'
        self.log.info(text)
        sql = f"select * from query_node_reform_info();"
        self.log.info(sql)
        status = Primary_SH.execut_db_sql(sql)
        self.log.info(status)
        self.assertIn('Normal reform',status, '执行失败' + text)

        text = '-----step3:手动启动备节点2 expect:启动节点2 OK-----'
        self.log.info(text)
        status = Primary_SH.exec_cm_ctl(mode='start', param='-n 2')
        self.log.info(status)
        self.assertIn('cm_ctl: start node successfully.', status, '执行失败' + text)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        time.sleep(30)
        text = '-----step4:主节点连接数据库并查询节点reform信息 expect:集群发生normal reform，节点1稳定，节点2加入集群-----'
        self.log.info(text)
        sql = f"select * from query_node_reform_info();"
        self.log.info(sql)
        status = Primary_SH.execut_db_sql(sql)
        self.log.info(status)
        self.assertIn('Normal reform', status, '执行失败' + text)

        text = '-----step5:集群failover并查询节点reform信息 expect:集群发生failover成功-----'
        self.log.info(text)
        stopdn = Primary_SH.exec_failover()
        self.log.info(stopdn)
        time.sleep(180)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        self.assertIn('cluster_state   : Degraded', status, '执行失败' + text)
        res1 = status.splitlines()[-1].split('|')[0].split('6001')[-1]
        res2 = status.splitlines()[-1].split('|')[1].split('6002')[-1]
        self.assertIn('S Primary Normal', res2, '执行失败' + text)
        sql = f"select * from query_node_reform_info();"
        self.log.info(sql)
        status = self.s1_comsh.execut_db_sql(sql)
        self.log.info(status)
        self.assertIn('Failover', status, '执行失败' + text)

        text = '-----step6:手动关闭集群 expect:关闭成功-----'
        self.log.info(text)
        status = Primary_SH.exec_cm_ctl(mode='stop')
        self.log.info(status)
        self.assertIn('cm_ctl: stop cluster successfully.', status, '执行失败' + text)

        text = '-----step7:手动启动集群 expect:启动成功-----'
        self.log.info(text)
        status = Primary_SH.exec_cm_ctl(mode='start')
        self.log.info(status)
        self.assertIn('cm_ctl: start cluster successfully.', status, '执行失败' + text)

        text = '-----step8:备1节点执行switchover切换为主节点; expect:执行成功-----'
        self.log.info(text)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        switch = Primary_SH.exec_cm_ctl(mode='switchover', param='-n 1', path=f'-D {macro.DB_INSTANCE_PATH}')
        self.log.info(switch)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        self.assertIn(self.constant.cm_switchover_success_msg, switch, '执行失败' + text)

        text = '-----step9:在新的主节点连接数据库并查询节点reform信息; expect:执行成功-----'
        self.log.info(text)
        sql = f"select * from query_node_reform_info();"
        self.log.info(sql)
        status = Primary_SH.execut_db_sql(sql)
        self.log.info(status)
        self.assertIn('(2 rows)', status, '执行失败' + text)

    def tearDown(self):
        text = '-----step10:恢复环境为初始集群状态; expect:成功-----'
        self.log.info(text)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        status = Primary_SH.check_cluster_core_status(status, wait_times=600)
        self.log.info(status)
        status = Primary_SH.exec_cm_ctl(mode='stop')
        self.log.info(status)
        self.assertIn('cm_ctl: stop cluster successfully.', status, '执行失败' + text)

        status = Primary_SH.exec_cm_ctl(mode='start')
        self.log.info(status)
        self.assertIn('cm_ctl: start cluster successfully.', status, '执行失败' + text)

        status = Primary_SH.exec_cm_ctl(mode='switchover', param='-a')
        self.log.info(status)
        self.assertIn(self.constant.cm_switchover_success_msg, status, '执行失败' + text)

        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)
        self.log.info(f'-----{os.path.basename(__file__)} end-----')
